//
// Created by wei.yang on 2021/8/20.
//
extern "C" {
#include "generate_pcm.h"
#include <libavformat/avformat.h>
#include <android/log.h>
}


/**
 * 生成一个PCM文件
 * @param inputVideoPath 输入的视频路径
 * @param outputPcmPath 输出的pcm路径
 */
void generatePcm(JNIEnv *env, jstring inputVideoPath, jstring outputPcmPath) {
    av_register_all();//注册编解码器
    //初始化AVFormatContext
    AVFormatContext *avFormatContext = NULL;
    AVCodecContext *avCodecContext = NULL;
    //打开文件，主要探测协议类型如果是网络文件则创建网络连接
    char *input = (char *) env->GetStringUTFChars(inputVideoPath, 0);
    int ret = avformat_open_input(&avFormatContext, input, NULL, NULL);
    if (ret < 0) {
        char buf[1024] = {0};
        av_strerror(ret, buf, sizeof(buf) - 1);
        __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%s", "打开文件失败:", buf);
        return;
    }
    //读取码流信息
    ret = avformat_find_stream_info(avFormatContext, NULL);
    if (ret < 0) {
        char buf[1024] = {0};
        av_strerror(ret, buf, sizeof(buf) - 1);
        __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%s", "读取码流失败", buf);
        avformat_close_input(&avFormatContext);
        return;
    }

    //读取音频信息
    int audioIndex = av_find_best_stream(avFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    if (audioIndex < 0) {
        __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%s", "未找到音频流:",
                            av_get_media_type_string(AVMEDIA_TYPE_AUDIO));
        return;
    }

    AVStream *audioStream = avFormatContext->streams[audioIndex];
    //序列号、采样率、采样格式、编码格式
    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "index", audioStream->index);
    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "sample_rate",
                        audioStream->codecpar->sample_rate);
    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "format",
                        audioStream->codecpar->format);
    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "codec_id",
                        audioStream->codecpar->codec_id);
    if (audioStream->duration != AV_NOPTS_VALUE) {
        int audioDuration = audioStream->duration * av_q2d(audioStream->time_base);
        __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "audio duration: %02d:%02d:%02d",
                            audioDuration / 3600, (audioDuration % 3600) / 60,
                            (audioDuration % 60));
    }
    //创建解码器
    avCodecContext = audioStream->codec;
    AVCodec *avCodec = avcodec_find_decoder(avCodecContext->codec_id);
    //打开解码器
    ret = avcodec_open2(avCodecContext, avCodec, NULL);
    if (ret < 0) {
        __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "打开解码器失败");
        return;
    }
    //提取码流
    AVPacket *pkt = av_packet_alloc();
    int pkt_count = 0;
    int print_max_count = 10;
    AVFrame *avFrame = NULL;
    int gotframe = 0;
    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "av_red_frame_start");
    while (true) {
        ret = av_read_frame(avFormatContext, pkt);
        if (ret < 0) {
            __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "av_red_frame_end");
            break;
        }
        if (pkt_count++ <= print_max_count) {
            if (pkt->stream_index == audioIndex) {//如果是音频数据
                ret = avcodec_decode_audio4(avCodecContext, avFrame, &gotframe, pkt);
                if (ret < 0) {
                    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "音频解码失败");
                    return;
                }
                //音频解码成功后取出数据
                pkt->data;
                pkt->stream_index;
            }
        }
        av_packet_unref(pkt);
    };
    __android_log_print(ANDROID_LOG_ERROR, "generatePcm", "%d", "av_red_frame_end");
    if (pkt) {
        av_packet_free(&pkt);
    }
    if (avFormatContext) {
        avformat_close_input(&avFormatContext);
    }

}
